HRI 2021: Visualizations and Statistical Significance

Viki Zygouras - 5/18/2020

In [1]:
!pip install colored
Requirement already satisfied: colored in c:\users\vikiz\anaconda3\lib\site-packages (1.4.2)
In [2]:
import chart_studio.plotly as py
import plotly.graph_objs as go
import plotly.figure_factory as ff
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
import numpy as np
from IPython.display import SVG, HTML
from scipy import stats
import plotly.io as pio
import plotly.express as px
from plotly import tools
from plotly.subplots import make_subplots
from statsmodels.stats.multicomp import pairwise_tukeyhsd
from statsmodels.stats.multicomp import MultiComparison
import itertools
import colored
import statsmodels.api as sm
from statsmodels.formula.api import ols
import statistics 
from plotly.subplots import make_subplots
import plotly.graph_objects as go

Import the cleaned data:

In [3]:
reciprocity = pd.read_csv("ReciprocityAnalysis.csv")
In [4]:
#Captialize agent names 
reciprocity['Agent'] = reciprocity['Agent'].str.capitalize()
In [5]:
#set colors for visuals
colors = ['rgb(238,166,101)', 'rgb(238,199,188)', 'rgb(154,196,196)']
agents = [ 'Jibo', 'Alexa','Computer']
behavior = reciprocity
In [6]:
#list of all behaviors for labels
behaviors = ['Short Response', 'Mhm' , 'Answer Question', 
             'Follow-Up Question', 'Exclamation', 'Relevancy', 
             'Move Toward', 'Move Away', 'Touch' ,'Point', 'Shrug',
             'Luring', 'Nod', 'Shake Head' , 'Tilt Head', 'Imitation', 'Imitation Dance',
             'Generic Dance', 'Waving', 'Hand Gesture', 'Switch Eye Contact', 'Look Away',
             'Glance at Others', 'Smile', 'Judgemental Eyebrow', 'Inquisitive Eyebrow',
             'Downward Frown', 'Mouth Open', 'Whisper', 'Laugh', 'Thank You', 'Compliment',
             'Defend', 'Insult', 'Judgemental Verbal', 'Angry Verbal', 'Interrupt']

Make function to run one way ANOVAs across agents:

In [7]:
#Will output one way ANOVA for all pairs of agents (i.e Jibo vs. Alexa, Jibo vs. Computer, Computer vs. Alexa). 
#Significant p-value results will be printed in purple. 

def anova_oneway(dataframe1):
    combinations = list(itertools.combinations(agents, 2)) #Creates all pairwise combinations of agents 
   
    print(colored.fg("black")  + "One Way ANOVAs:")
    
    for combo in combinations: 
        pvalString = ''
        #run oneway anova here - will use the same dataframe passed in 
        oneway = stats.f_oneway(
        dataframe1[(dataframe1["Agent"] == combo[0])].Proportion, #Take first agent in pair 
        dataframe1[(dataframe1["Agent"] == combo[1])].Proportion) #Take second agent in pair 
        
        pval = oneway[1]
        
        #just for printing the purple significant p-vals 
        if pval < 0.05:
            pvalString = colored.fg("magenta_3a") + str(pval)
        else: 
            pvalString = colored.fg("black") + str(pval)
            
        resultstr = colored.fg("black")  + combo[0] + " vs. " + combo[1] + " P-Value: " + pvalString
       
        print(resultstr) 

Histogram of all interactions by agent

In [8]:
#Plotly Express Histogram 
fig = px.histogram(reciprocity, x="Description", color="Agent",barmode ='group', barnorm = 'fraction'
                 ,color_discrete_sequence=colors).update_xaxes(categoryorder="total descending")

#Formatting
fig.update_layout(
        legend_title_text='Agent',
        yaxis_title='Proportion of Behaviors',
        xaxis_title='Behavior',
        title ='Engagement Across Agents' ,
        width=1100, height=900,
        xaxis=dict(type='category'),
        plot_bgcolor = 'white',
        boxmode = 'group')

fig.update_yaxes(gridcolor='#D3D3D3') 
#fig.show()

Box Plots of All Behaviors:

In [9]:
temp = behavior
total = temp[["Family","Participant","Agent","Description", "Type"]]
total = total.groupby(['Participant','Agent', 'Description']).size().reset_index(name='counts')

combined = total.groupby('Participant')[['counts']].sum().reset_index()
allBehaviors = pd.merge(total, combined, on='Participant')

allBehaviors['Proportion'] = allBehaviors["counts_x"]/allBehaviors["counts_y"]
fig = go.Figure()

traces = []

#append each behavior to overall graph 
for i in range(len(agents)):  
    currentTrace = go.Box(y=allBehaviors[allBehaviors['Agent'] == agents[i]].Proportion,x = allBehaviors['Description'],
                          name = agents[i], marker = dict(color = colors[i]))
    traces.append(currentTrace)
    
fig.add_traces(traces)
fig.update_layout(
        legend_title_text='Agent',
        yaxis_title='Proportion of Behaviors',
        xaxis_title='Behaviors',
        title ='Voice-User Interface Agent Behaviors Grouped by Participant' ,
        width=1500, height=700,
        plot_bgcolor = 'white',
        xaxis=dict(type='category'),
        boxmode = 'group')

fig.update_yaxes(gridcolor='#D3D3D3')
#fig.show()

Testing Significance: Children vs. Adults

Test if there's a difference between adults and children across all behaviors and across agents.

In [10]:
#Make temp df 
N = behavior
Nagent = N[["Family","Participant","Agent","Behavior", "isAdult", "isChild"]]
Nagent = Nagent.groupby(['Participant', 'Behavior', 'isAdult']).size().reset_index(name='counts')
totals = Nagent.groupby('Participant')[['counts']].sum().reset_index()
Nagent = pd.merge(Nagent, totals, on='Participant')
Nagent['Proportion'] = Nagent["counts_x"]/Nagent["counts_y"]

#Split by kids and adults
kids = Nagent[Nagent["isAdult"] == 0]
adults = Nagent[Nagent["isAdult"] == 1]

#Behavior Analysis: Adults vs. Children Overall Behavior 
result = stats.f_oneway(kids.Proportion, adults.Proportion)
print("One Way ANOVA: \nChildren vs. Adults Across Behavior\n","P-Value:",result[1])
One Way ANOVA: 
Children vs. Adults Across Behavior
 P-Value: 0.9637000391455517
In [11]:
result
Out[11]:
F_onewayResult(statistic=0.0020733408139813857, pvalue=0.9637000391455517)
In [12]:
model = ols('Proportion ~ C(isAdult)', data=Nagent).fit()
anova_table = sm.stats.anova_lm(model, typ=2)
anova_table
Out[12]:
sum_sq df F PR(>F)
C(isAdult) 0.000011 1.0 0.002073 0.9637
Residual 2.512299 496.0 NaN NaN
In [13]:
temp = behavior 
Nagent = temp[["Family","Participant","Agent","Behavior", "isAdult", "isChild"]]
Nagent = Nagent.groupby(['Participant', 'Agent', 'isAdult']).size().reset_index(name='counts')
totals = Nagent.groupby('Participant')[['counts']].sum().reset_index()
Nagent = pd.merge(Nagent, totals, on='Participant')
Nagent['Proportion'] = Nagent["counts_x"]/Nagent["counts_y"]

#Split by kids and adults
kids = Nagent[Nagent["isAdult"] == 0]
adults = Nagent[Nagent["isAdult"] == 1]

#Behavior Analysis: Adults vs. Children Overall Behavior 
result = stats.f_oneway(kids.Proportion, adults.Proportion)
print("One Way ANOVA:\nChildren vs. Adults Across Agents\n","P-Value:",result[1])
One Way ANOVA:
Children vs. Adults Across Agents
 P-Value: 0.8462361604606472

There is no difference between children and adults across behaviors and across agents.

Visualizing and Testing Significance of Positive vs. Not Positive Interactions Overall:

In [14]:
#Data for plot below: make a copy of a subset of the df 
pos = behavior[["Family","Participant","Agent","Description", "Positive", "Type"]]

#Group by participant and calculate proportions 
pos = pos.groupby([ "Participant", 'Agent', 'Positive']).size().reset_index(name='counts')
totals = pos.groupby("Participant")[['counts']].sum().reset_index()
pos = pd.merge(pos, totals, on="Participant")
pos['Proportion'] = pos["counts_x"]/pos["counts_y"]

#Want to isolate the positive values
neg = pos[pos['Positive'] == 0]
pos = pos[pos['Positive'] == 1]
#Plot the positive behavior data  
positiveFigure = go.Figure()

#Create a box for each agent and append to overall plot - adapted & modified from previous notebooks 
traces = []
for i in range(len(agents)):
    positive = go.Box(y=pos[pos["Agent"] == agents[i]].Proportion, name = "<b>Positive</b>", marker = dict(color = colors[i]),
                    showlegend = False)
    nonverb = go.Box(y=neg[neg["Agent"] == agents[i]].Proportion, name = "<b>Not Positive</b>", marker = dict(color = colors[i]),
                    showlegend=False)
    
    traces.append(positive)
    traces.append(nonverb)
    
positiveFigure.add_traces(traces)

positiveFigure.update_layout(
        
        title_text ='<b>Sentiment of User Response</b>' ,
        width=800, height=800,
        plot_bgcolor = 'white',
        boxmode = 'group',
        font=dict(
        size=20,
        color="#000000",
        family="Calibri, Body",)
)

positiveFigure.update_yaxes(gridcolor='#D3D3D3')  
positiveFigure.update(layout=dict(title=dict(x=0.5)))
positiveFigure.show()
positiveFigure.write_image("images/sentiment.svg")

One Way ANOVAs for Positive and Not Positive:

In [15]:
#across the three agents - positive
stats.f_oneway(pos[(pos["Agent"] == "Jibo")].Proportion,pos[(pos["Agent"] == "Computer")].Proportion,pos[(pos["Agent"] == "Alexa")].Proportion)
Out[15]:
F_onewayResult(statistic=38.21301046954647, pvalue=2.0513712594212987e-12)
In [16]:
#across the three agents - negative
stats.f_oneway(neg[(neg["Agent"] == "Jibo")].Proportion,neg[(neg["Agent"] == "Computer")].Proportion,neg[(neg["Agent"] == "Alexa")].Proportion)
Out[16]:
F_onewayResult(statistic=1.034159271831768, pvalue=0.35995453533586497)

Run ANOVAs with post-hoc Tukey HSD to check significance of visual:

In [17]:
print("Positive: \n")
anova_oneway(pos)
print("\nNot Positive: \n")
anova_oneway(neg)
Positive: 

One Way ANOVAs:
Jibo vs. Alexa P-Value: 9.485959615252714e-10
Jibo vs. Computer P-Value: 9.297290308415643e-09
Alexa vs. Computer P-Value: 0.8605128599126033

Not Positive: 

One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.23898667777639035
Jibo vs. Computer P-Value: 0.3139718860127325
Alexa vs. Computer P-Value: 0.7183800041112678
In [23]:
model = ols('Proportion ~ C(Agent)', data=neg).fit()
anova_table = sm.stats.anova_lm(model, typ=2)
#anova_table
In [19]:
MultiComp = MultiComparison(pos['Proportion'],pos["Agent"])
print(MultiComp.tukeyhsd().summary())
 Multiple Comparison of Means - Tukey HSD, FWER=0.05  
======================================================
 group1   group2  meandiff p-adj  lower  upper  reject
------------------------------------------------------
   Alexa Computer  -0.0051   0.9 -0.0856 0.0754  False
   Alexa     Jibo   0.2325 0.001  0.1563 0.3087   True
Computer     Jibo   0.2376 0.001  0.1622 0.3129   True
------------------------------------------------------
In [20]:
MultiComp = MultiComparison(neg['Proportion'],neg["Agent"])
print(MultiComp.tukeyhsd().summary())
  Multiple Comparison of Means - Tukey HSD, FWER=0.05  
=======================================================
 group1   group2  meandiff p-adj   lower  upper  reject
-------------------------------------------------------
   Alexa Computer    0.005    0.9 -0.0418 0.0518  False
   Alexa     Jibo   0.0277 0.3718 -0.0211 0.0765  False
Computer     Jibo   0.0226 0.4984 -0.0251 0.0703  False
-------------------------------------------------------
In [21]:
print('Computer: ', statistics.mean(pos[(pos["Agent"] == "Computer")].Proportion))
print('Jibo: ', statistics.mean(pos[(pos["Agent"] == "Jibo")].Proportion))
print('Alexa: ', statistics.mean(pos[(pos["Agent"] == "Alexa")].Proportion))
Computer:  0.09470345457230944
Jibo:  0.3322541246296965
Alexa:  0.09976421869452906
In [22]:
print('Computer: ', statistics.stdev(pos[(pos["Agent"] == "Computer")].Proportion))
print('Jibo: ', statistics.stdev(pos[(pos["Agent"] == "Jibo")].Proportion))
print('Alexa: ', statistics.stdev(pos[(pos["Agent"] == "Alexa")].Proportion))
Computer:  0.12240939716728852
Jibo:  0.14374095574905177
Alexa:  0.07582006882667011

Visualizing and Testing Significance of Verbal vs Non-Verbal Behaviors

In [24]:
verbal = behavior[["Family","Participant","Agent","Description", "Positive", "Verbal" ,"Type"]]

#Group by participant and calculate proportions 
verbal = verbal.groupby([ "Participant", 'Agent', 'Verbal']).size().reset_index(name='counts')
totals = verbal.groupby("Participant")[['counts']].sum().reset_index()
verbal = pd.merge(verbal, totals, on="Participant")
verbal['Proportion'] = verbal["counts_x"]/verbal["counts_y"]

#Want to isolate the positive values
nonverbal = verbal[verbal['Verbal'] == 0]
verbal = verbal[verbal['Verbal'] == 1]

verbalFigure = go.Figure()

#Create a box for each agent and append to overall plot - adapted & modified from previous notebooks 
traces = []
for i in range(len(agents)):
    current = go.Box(y=verbal[verbal["Agent"] == agents[i]].Proportion, name = "<b>Verbal</b>", marker = dict(color = colors[i]),
                    showlegend = False)
    nonverb = go.Box(y=nonverbal[nonverbal["Agent"] == agents[i]].Proportion, name = "<b>Nonverbal</b>", marker = dict(color = colors[i]),
                     showlegend=False)
    traces.append(current)
    traces.append(nonverb)
    
verbalFigure.add_traces(traces)


verbalFigure.update_layout(
        
        title_text ='<b>Verbal and Nonverbal User Response</b>' ,
        width=800, height=800,
        plot_bgcolor = 'white',
        boxmode = 'group',
        font=dict(
        size=20,
        color="#000000",
        family="Calibri, Body",)
)

verbalFigure.update_yaxes(gridcolor='#D3D3D3')  
verbalFigure.update(layout=dict(title=dict(x=0.5)))
verbalFigure.show()
verbalFigure.write_image("images/verbal.svg")
In [25]:
#across the three agents - verbal
stats.f_oneway(verbal[(verbal["Agent"] == "Jibo")].Proportion,verbal[(verbal["Agent"] == "Computer")].Proportion,verbal[(verbal["Agent"] == "Alexa")].Proportion)
Out[25]:
F_onewayResult(statistic=14.45669522707534, pvalue=4.021806681633828e-06)
In [26]:
#across the three agents - nonverbal
stats.f_oneway(nonverbal[(nonverbal["Agent"] == "Jibo")].Proportion,nonverbal[(nonverbal["Agent"] == "Computer")].Proportion,nonverbal[(nonverbal["Agent"] == "Alexa")].Proportion)
Out[26]:
F_onewayResult(statistic=37.905398264797746, pvalue=8.484769728724066e-13)
In [27]:
#model for verbal
model = ols('Proportion ~ C(Agent)', data=verbal).fit()
anova_table = sm.stats.anova_lm(model, typ=2)
anova_table
Out[27]:
sum_sq df F PR(>F)
C(Agent) 0.109315 2.0 14.456695 0.000004
Residual 0.317586 84.0 NaN NaN
In [28]:
#model for nonverbal
model = ols('Proportion ~ C(Agent)', data=nonverbal).fit()
anova_table = sm.stats.anova_lm(model, typ=2)
anova_table
Out[28]:
sum_sq df F PR(>F)
C(Agent) 0.795596 2.0 37.905398 8.484770e-13
Residual 0.986483 94.0 NaN NaN
In [29]:
print("Verbal")
anova_oneway(verbal)
print("\nNonVerbal")
anova_oneway(nonverbal)
Verbal
One Way ANOVAs:
Jibo vs. Alexa P-Value: 5.56006209950865e-05
Jibo vs. Computer P-Value: 0.00017613149180516723
Alexa vs. Computer P-Value: 0.5968465467139217

NonVerbal
One Way ANOVAs:
Jibo vs. Alexa P-Value: 1.7248661120662972e-10
Jibo vs. Computer P-Value: 2.1446474078171753e-09
Alexa vs. Computer P-Value: 0.9798933398438752
In [30]:
MultiComp = MultiComparison(verbal['Proportion'],verbal["Agent"])
print(MultiComp.tukeyhsd().summary())
 Multiple Comparison of Means - Tukey HSD, FWER=0.05  
======================================================
 group1   group2  meandiff p-adj  lower  upper  reject
------------------------------------------------------
   Alexa Computer   0.0064   0.9 -0.0325 0.0453  False
   Alexa     Jibo   0.0776 0.001  0.0391 0.1162   True
Computer     Jibo   0.0712 0.001   0.033 0.1094   True
------------------------------------------------------
In [31]:
MultiComp = MultiComparison(nonverbal['Proportion'],nonverbal["Agent"])
print(MultiComp.tukeyhsd().summary())
 Multiple Comparison of Means - Tukey HSD, FWER=0.05  
======================================================
 group1   group2  meandiff p-adj  lower  upper  reject
------------------------------------------------------
   Alexa Computer  -0.0006   0.9 -0.0616 0.0604  False
   Alexa     Jibo   0.1908 0.001  0.1298 0.2519   True
Computer     Jibo   0.1914 0.001  0.1314 0.2515   True
------------------------------------------------------
In [32]:
print('Computer: ', statistics.mean(verbal[(verbal["Agent"] == "Computer")].Proportion))
print('Jibo: ', statistics.mean(verbal[(verbal["Agent"] == "Jibo")].Proportion))
print('Alexa: ', statistics.mean(verbal[(verbal["Agent"] == "Alexa")].Proportion))
Computer:  0.08341518891873329
Jibo:  0.15464223050348896
Alexa:  0.07700376116797945
In [33]:
print('Computer: ', statistics.stdev(verbal[(verbal["Agent"] == "Computer")].Proportion))
print('Jibo: ', statistics.stdev(verbal[(verbal["Agent"] == "Jibo")].Proportion))
print('Alexa: ', statistics.stdev(verbal[(verbal["Agent"] == "Alexa")].Proportion))
Computer:  0.04660539410364718
Jibo:  0.08383130597580404
Alexa:  0.04429086806107992
In [34]:
print('Computer: ', statistics.mean(nonverbal[(nonverbal["Agent"] == "Computer")].Proportion))
print('Jibo: ', statistics.mean(nonverbal[(nonverbal["Agent"] == "Jibo")].Proportion))
print('Alexa: ', statistics.mean(nonverbal[(nonverbal["Agent"] == "Alexa")].Proportion))
Computer:  0.13307655391282935
Jibo:  0.3245208569111481
Alexa:  0.1336755755989178
In [35]:
print('Computer: ', statistics.stdev(nonverbal[(nonverbal["Agent"] == "Computer")].Proportion))
print('Jibo: ', statistics.stdev(nonverbal[(nonverbal["Agent"] == "Jibo")].Proportion))
print('Alexa: ', statistics.stdev(nonverbal[(nonverbal["Agent"] == "Alexa")].Proportion))
Computer:  0.10705510140369319
Jibo:  0.11607120392803476
Alexa:  0.07929201708160256

More Visualizations and Tests Below: Exploring Significance Across Categories

Overall Categories (Not Split on Anything):

In [39]:
pos = behavior[["Family","Participant","Agent","Description", "Positive", "Acknowledgement Verbal","Negative Verbal" , "Positive Verbal","Head", "Hand", "Face", "Eye", "Body"]]

#Group by participant and calculate proportions 
pos = pos.groupby([ "Participant", 'Agent', "Positive" ,"Head", "Hand", "Face", "Eye", "Body", "Acknowledgement Verbal", "Positive Verbal", "Negative Verbal"]).size().reset_index(name='counts')
totals = pos.groupby("Participant")[['counts']].sum().reset_index()
pos = pd.merge(pos, totals, on="Participant")
pos['Proportion'] = pos["counts_x"]/pos["counts_y"]

#Want to isolate the positive values of each category 

hand = pos[pos['Hand'] == 1]
head = pos[pos['Head'] == 1]
body = pos[pos['Body'] == 1]
eye = pos[pos['Eye'] == 1]
posverb = pos[pos["Positive Verbal"] == 1]
ack = pos[pos["Acknowledgement Verbal"] == 1]
negV = pos[pos["Negative Verbal" ] == 1]
fig = go.Figure()

#Create a box for each agent and append to overall plot - adapted & modified from previous notebooks 
traces = []
for i in range(len(agents)):
    current = go.Box(y=hand[hand["Agent"] == agents[i]].Proportion, name = "Hand", marker = dict(color = colors[i]),
                    showlegend = False)
    nonverb = go.Box(y=head[head["Agent"] == agents[i]].Proportion, name = "Head", marker = dict(color = colors[i]),
                    showlegend=False)
    bod = go.Box(y=body[body["Agent"] == agents[i]].Proportion, name = "Body", marker = dict(color = colors[i]),
                    showlegend=False)
    ey = go.Box(y=eye[eye["Agent"] == agents[i]].Proportion, name = "Eye", marker = dict(color = colors[i]),
                    showlegend=False)
    pv = go.Box(y=posverb[posverb["Agent"] == agents[i]].Proportion, name = "Positive Verbal", marker = dict(color = colors[i]),
                    showlegend=False)
    ackno = go.Box(y=ack[ack["Agent"] == agents[i]].Proportion, name = "Acknowledgement Verbal", marker = dict(color = colors[i]),
                    showlegend=False)
    negative = go.Box(y=negV[negV["Agent"] == agents[i]].Proportion, name = "Negative Verbal", marker = dict(color = colors[i]),
                    showlegend=False)
    traces.append(current)
    traces.append(nonverb)
    traces.append(bod)
    traces.append(ey)
    traces.append(pv)
    traces.append(ackno)
    traces.append(negative)
    
    
    
fig.add_traces(traces)

fig.update_layout(
        legend_title_text='Agent',
        yaxis_title='Proportion of Behaviors',
        xaxis_title='Agent',
        title ='All Behaviors Split by Categories' ,
        width=800, height=800,
        plot_bgcolor = 'white',
        boxmode = 'group',
        boxgap = 0.0001,
        boxgroupgap = 0.001)


dfs = [body, eye, posverb,ack,negV, hand, head]
labels = ["Body", "Eye", "Positive Verbal", "ack", "Negative Verbal", "Hand", "Head"]

#Isolate the positive values for each agent
for i in range(len(dfs)):
    print( "\n" +labels[i].capitalize() )
    anova_oneway(dfs[i])

fig.update_yaxes(gridcolor='#D3D3D3')               
fig.show()
Body
One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.43287948734105175
Jibo vs. Computer P-Value: 0.004825055583415762
Alexa vs. Computer P-Value: 0.1200105189737902

Eye
One Way ANOVAs:
Jibo vs. Alexa P-Value: 4.322425538681245e-06
Jibo vs. Computer P-Value: 1.3951684740094404e-05
Alexa vs. Computer P-Value: 0.8628516295625248

Positive verbal
One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.00113902503763203
Jibo vs. Computer P-Value: 0.01473821360416647
Alexa vs. Computer P-Value: 0.9053170684133829

Ack
One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.027917820202711597
Jibo vs. Computer P-Value: 0.04950745446224082
Alexa vs. Computer P-Value: 0.6077798239774549

Negative verbal
One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.2154372733672476
Jibo vs. Computer P-Value: 0.7792483195549069
Alexa vs. Computer P-Value: 0.31706790095215875

Hand
One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.25498439685009033
Jibo vs. Computer P-Value: 0.20090331909333398
Alexa vs. Computer P-Value: 0.6830400942626329

Head
One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.5379660062601974
Jibo vs. Computer P-Value: 0.5796965204877722
Alexa vs. Computer P-Value: 0.3069246497965867

Categories Split on Positive

In [40]:
pos = behavior[["Family","Participant","Agent","Description", "Positive", "Acknowledgement Verbal","Negative Verbal" , "Positive Verbal","Head", "Hand", "Face", "Eye", "Body"]]

#Group by participant and calculate proportions 
pos = pos.groupby([ "Participant", 'Agent', "Positive" ,"Head", "Hand", "Face", "Eye", "Body", "Acknowledgement Verbal", "Positive Verbal", "Negative Verbal"]).size().reset_index(name='counts')
totals = pos.groupby("Participant")[['counts']].sum().reset_index()
pos = pd.merge(pos, totals, on="Participant")
pos['Proportion'] = pos["counts_x"]/pos["counts_y"]

#Want to isolate the positive values
pos = pos[pos['Positive'] == 1]
hand = pos[pos['Hand'] == 1]
head = pos[pos['Head'] == 1]
body = pos[pos['Body'] == 1]
eye = pos[pos['Eye'] == 1]
posverb = pos[pos["Positive Verbal"] == 1]
ack = pos[pos["Acknowledgement Verbal"] == 1]
negV = pos[pos["Negative Verbal" ] == 1]
fig = go.Figure()

#Create a box for each agent and append to overall plot - adapted & modified from previous notebooks 
traces = []
for i in range(len(agents)):
    current = go.Box(y=hand[hand["Agent"] == agents[i]].Proportion, name = "Hand", marker = dict(color = colors[i]),
                    showlegend = False)
    nonverb = go.Box(y=head[head["Agent"] == agents[i]].Proportion, name = "Head", marker = dict(color = colors[i]),
                    showlegend=False)
    bod = go.Box(y=body[body["Agent"] == agents[i]].Proportion, name = "Body", marker = dict(color = colors[i]),
                    showlegend=False)
    ey = go.Box(y=eye[eye["Agent"] == agents[i]].Proportion, name = "Eye", marker = dict(color = colors[i]),
                    showlegend=False)
    pv = go.Box(y=posverb[posverb["Agent"] == agents[i]].Proportion, name = "Positive Verbal", marker = dict(color = colors[i]),
                    showlegend=False)
    ackno = go.Box(y=ack[ack["Agent"] == agents[i]].Proportion, name = "Acknowledgement Verbal", marker = dict(color = colors[i]),
                    showlegend=False)
    negative = go.Box(y=negV[negV["Agent"] == agents[i]].Proportion, name = "Negative Verbal", marker = dict(color = colors[i]),
                    showlegend=False)
    traces.append(current)
    traces.append(nonverb)
    traces.append(bod)
    traces.append(ey)
    traces.append(pv)
    traces.append(ackno)
    traces.append(negative)
    
    
    
fig.add_traces(traces)

fig.update_layout(
        legend_title_text='Agent',
        yaxis_title='Proportion of Behaviors',
        xaxis_title='Agent',
        title ='Positive Behaviors Split by Categories' ,
        width=800, height=800,
        plot_bgcolor = 'white',
        boxmode = 'group',
        boxgap = 0.0001,
        boxgroupgap = 0.001)


dfs = [body, eye, posverb,ack,negV, hand, head]
labels = ["Body", "Eye", "Positive Verbal", "ack", "Negative Verbal", "Hand", "Head"]

#Isolate the positive values for each agent
for i in range(len(dfs)):
    print( "\n" +labels[i].capitalize() )
    anova_oneway(dfs[i])

fig.update_yaxes(gridcolor='#D3D3D3')               
fig.show()
Body
One Way ANOVAs:
Jibo vs. Alexa P-Value: nan
Jibo vs. Computer P-Value: 0.6000495748050568
Alexa vs. Computer P-Value: nan

Eye
One Way ANOVAs:
Jibo vs. Alexa P-Value: 1.0703950944868912e-06
Jibo vs. Computer P-Value: 7.215927555885953e-05
Alexa vs. Computer P-Value: 0.8949518126440085

Positive verbal
One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.0033678692824990384
Jibo vs. Computer P-Value: 0.10330686709069262
Alexa vs. Computer P-Value: 0.6871476324406072

Ack
One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.010665101076763944
Jibo vs. Computer P-Value: 0.001786328517522446
Alexa vs. Computer P-Value: 0.9403643680010001

Negative verbal
One Way ANOVAs:
Jibo vs. Alexa P-Value: nan
Jibo vs. Computer P-Value: 0.19861125340691482
Alexa vs. Computer P-Value: nan

Hand
One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.27008446176375367
Jibo vs. Computer P-Value: nan
Alexa vs. Computer P-Value: 0.2769347888368075

Head
One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.5634969148064675
Jibo vs. Computer P-Value: 0.6091192465427119
Alexa vs. Computer P-Value: 0.9583403362587017
C:\Users\vikiz\anaconda3\lib\site-packages\scipy\stats\stats.py:3339: RuntimeWarning:

invalid value encountered in double_scalars

C:\Users\vikiz\anaconda3\lib\site-packages\scipy\stats\stats.py:3348: RuntimeWarning:

invalid value encountered in double_scalars

Categories Split by Not Positive

In [41]:
pos = behavior[["Family","Participant","Agent","Description", "Positive", "Acknowledgement Verbal","Negative Verbal" , "Positive Verbal","Head", "Hand", "Face", "Eye", "Body"]]

#Group by participant and calculate proportions 
pos = pos.groupby([ "Participant", 'Agent', "Positive" ,"Head", "Hand", "Face", "Eye", "Body", "Acknowledgement Verbal", "Positive Verbal", "Negative Verbal"]).size().reset_index(name='counts')
totals = pos.groupby("Participant")[['counts']].sum().reset_index()
pos = pd.merge(pos, totals, on="Participant")
pos['Proportion'] = pos["counts_x"]/pos["counts_y"]

#Want to isolate the positive values
pos = pos[pos['Positive'] == 0]
hand = pos[pos['Hand'] == 1]
head = pos[pos['Head'] == 1]
body = pos[pos['Body'] == 1]
eye = pos[pos['Eye'] == 1]
posverb = pos[pos["Positive Verbal"] == 1]
ack = pos[pos["Acknowledgement Verbal"] == 1]
negV = pos[pos["Negative Verbal" ] == 1]
fig = go.Figure()

#Create a box for each agent and append to overall plot - adapted & modified from previous notebooks 
traces = []
for i in range(len(agents)):
    current = go.Box(y=hand[hand["Agent"] == agents[i]].Proportion, name = "Hand", marker = dict(color = colors[i]),
                    showlegend = False)
    nonverb = go.Box(y=head[head["Agent"] == agents[i]].Proportion, name = "Head", marker = dict(color = colors[i]),
                    showlegend=False)
    bod = go.Box(y=body[body["Agent"] == agents[i]].Proportion, name = "Body", marker = dict(color = colors[i]),
                    showlegend=False)
    ey = go.Box(y=eye[eye["Agent"] == agents[i]].Proportion, name = "Eye", marker = dict(color = colors[i]),
                    showlegend=False)
    pv = go.Box(y=posverb[posverb["Agent"] == agents[i]].Proportion, name = "Positive Verbal", marker = dict(color = colors[i]),
                    showlegend=False)
    ackno = go.Box(y=ack[ack["Agent"] == agents[i]].Proportion, name = "Acknowledgement Verbal", marker = dict(color = colors[i]),
                    showlegend=False)
    negative = go.Box(y=negV[negV["Agent"] == agents[i]].Proportion, name = "Negative Verbal", marker = dict(color = colors[i]),
                    showlegend=False)
    traces.append(current)
    traces.append(nonverb)
    traces.append(bod)
    traces.append(ey)
    traces.append(pv)
    traces.append(ackno)
    traces.append(negative)
    
    
    
fig.add_traces(traces)

fig.update_layout(
        legend_title_text='Agent',
        yaxis_title='Proportion of Behaviors',
        xaxis_title='Agent',
        title ='Not Positive Behaviors Split by Categories' ,
        width=800, height=800,
        plot_bgcolor = 'white',
        boxmode = 'group',
        boxgap = 0.0001,
        boxgroupgap = 0.001)


dfs = [body, eye, posverb,ack,negV, hand, head]
labels = ["body", "eye", "posverb", "ack", "negV", "hand", "head"]

#Isolate the positive values for each agent
for i in range(len(dfs)):
    print(labels[i].capitalize())
    anova_oneway(dfs[i])

fig.update_yaxes(gridcolor='#D3D3D3')               
fig.show()
Body
One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.4160231712131791
Jibo vs. Computer P-Value: 0.8694360491298547
Alexa vs. Computer P-Value: 0.39230807813048546
Eye
One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.07605239292010738
Jibo vs. Computer P-Value: 0.031019601098399536
Alexa vs. Computer P-Value: 0.7020678594481119
Posverb
One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.11425287980451683
Jibo vs. Computer P-Value: 0.7556246677067342
Alexa vs. Computer P-Value: 0.1816869593805249
Ack
One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.6707355991876548
Jibo vs. Computer P-Value: 0.17510935535002337
Alexa vs. Computer P-Value: 0.3485286060473832
Negv
One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.3972342560110237
Jibo vs. Computer P-Value: 0.79096984109231
Alexa vs. Computer P-Value: 0.5011139969919642
Hand
One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.16320376621684332
Jibo vs. Computer P-Value: 0.16165350034522336
Alexa vs. Computer P-Value: 0.7237563731626881
Head
One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.813885411786395
Jibo vs. Computer P-Value: 0.31101567103162364
Alexa vs. Computer P-Value: 0.2618309244818802

Categories Split on In Sync

In [42]:
pos = behavior[["Participant", "Family","InSync","Agent","Description", "Acknowledgement Verbal","Negative Verbal" , "Positive Verbal","Head", "Hand", "Face", "Eye", "Body"]]

#Group by participant and calculate proportions 
pos = pos.groupby([ "Participant", 'Agent', "InSync" ,"Head", "Hand", "Face", "Eye", "Body", "Acknowledgement Verbal", "Positive Verbal", "Negative Verbal"]).size().reset_index(name='counts')
totals = pos.groupby("Participant")[['counts']].sum().reset_index()
pos = pd.merge(pos, totals, on="Participant")
pos['Proportion'] = pos["counts_x"]/pos["counts_y"]

#Want to isolate the positive values
pos = pos[pos['InSync'] == 1]

hand = pos[pos['Hand'] == 1]
head = pos[pos['Head'] == 1]
body = pos[pos['Body'] == 1]
eye = pos[pos['Eye'] == 1]
posverb = pos[pos["Positive Verbal"] == 1]
ack = pos[pos["Acknowledgement Verbal"] == 1]
negV = pos[pos["Negative Verbal" ] == 1]
fig = go.Figure()

#Create a box for each agent and append to overall plot - adapted & modified from previous notebooks 
traces = []
for i in range(len(agents)):
    current = go.Box(y=hand[hand["Agent"] == agents[i]].Proportion, name = "Hand", marker = dict(color = colors[i]),
                    showlegend = False)
    nonverb = go.Box(y=head[head["Agent"] == agents[i]].Proportion, name = "Head", marker = dict(color = colors[i]),
                    showlegend=False)
    bod = go.Box(y=body[body["Agent"] == agents[i]].Proportion, name = "Body", marker = dict(color = colors[i]),
                    showlegend=False)
    ey = go.Box(y=eye[eye["Agent"] == agents[i]].Proportion, name = "Eye", marker = dict(color = colors[i]),
                    showlegend=False)
    pv = go.Box(y=posverb[posverb["Agent"] == agents[i]].Proportion, name = "Positive Verbal", marker = dict(color = colors[i]),
                    showlegend=False)
    ackno = go.Box(y=ack[ack["Agent"] == agents[i]].Proportion, name = "Acknowledgement Verbal", marker = dict(color = colors[i]),
                    showlegend=False)
    negative = go.Box(y=negV[negV["Agent"] == agents[i]].Proportion, name = "Negative Verbal", marker = dict(color = colors[i]),
                    showlegend=False)
    traces.append(current)
    traces.append(nonverb)
    traces.append(bod)
    traces.append(ey)
    traces.append(pv)
    traces.append(ackno)
    traces.append(negative)
    
    
    
fig.add_traces(traces)

fig.update_layout(
        legend_title_text='Agent',
        yaxis_title='Proportion of Behaviors',
        xaxis_title='Agent',
        title ='In Sync Behaviors Split by Categories' ,
        width=800, height=800,
        plot_bgcolor = 'white',
        boxmode = 'group',
        boxgap = 0.0001,
        boxgroupgap = 0.001)


dfs = [body, eye, posverb,ack,negV, hand, head]
labels = ["body", "eye", "posverb", "ack", "negV", "hand", "head"]

#Isolate the positive values for each agent
for i in range(len(dfs)):
    print(labels[i].capitalize())
    anova_oneway(dfs[i])

fig.update_yaxes(gridcolor='#D3D3D3')               
fig.show()
Body
One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.5378145382313086
Jibo vs. Computer P-Value: 0.8907365291636566
Alexa vs. Computer P-Value: 0.3766048993582062
Eye
One Way ANOVAs:
Jibo vs. Alexa P-Value: 1.774572300295158e-05
Jibo vs. Computer P-Value: 7.024598251298656e-06
Alexa vs. Computer P-Value: 0.5949396005776821
Posverb
One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.011593579117270067
Jibo vs. Computer P-Value: 0.22996443252401833
Alexa vs. Computer P-Value: 0.5812478399584315
Ack
One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.043764352516842825
Jibo vs. Computer P-Value: 0.04214031670034008
Alexa vs. Computer P-Value: 0.8251548126700214
Negv
One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.06683451759266376
Jibo vs. Computer P-Value: 0.5366731070936652
Alexa vs. Computer P-Value: 0.5298384802547842
Hand
One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.598458475467035
Jibo vs. Computer P-Value: 0.7115223906080297
Alexa vs. Computer P-Value: 0.31844865550058127
Head
One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.18278149878956518
Jibo vs. Computer P-Value: 0.08331690774352746
Alexa vs. Computer P-Value: 0.5904315373029514

Categories Split on Mismatch

In [43]:
pos = behavior[["Participant", "Family","InSync","Agent","Description", "Acknowledgement Verbal","Negative Verbal" , "Positive Verbal","Head", "Hand", "Face", "Eye", "Body"]]

#Group by participant and calculate proportions 
pos = pos.groupby([ "Participant", 'Agent', "InSync" ,"Head", "Hand", "Face", "Eye", "Body", "Acknowledgement Verbal", "Positive Verbal", "Negative Verbal"]).size().reset_index(name='counts')
totals = pos.groupby("Participant")[['counts']].sum().reset_index()
pos = pd.merge(pos, totals, on="Participant")
pos['Proportion'] = pos["counts_x"]/pos["counts_y"]

#Want to isolate the positive values
pos = pos[pos['InSync'] == 0]

hand = pos[pos['Hand'] == 1]
head = pos[pos['Head'] == 1]
body = pos[pos['Body'] == 1]
eye = pos[pos['Eye'] == 1]
posverb = pos[pos["Positive Verbal"] == 1]
ack = pos[pos["Acknowledgement Verbal"] == 1]
negV = pos[pos["Negative Verbal" ] == 1]
fig = go.Figure()

#Create a box for each agent and append to overall plot - adapted & modified from previous notebooks 
traces = []
for i in range(len(agents)):
    current = go.Box(y=hand[hand["Agent"] == agents[i]].Proportion, name = "Hand", marker = dict(color = colors[i]),
                    showlegend = False)
    nonverb = go.Box(y=head[head["Agent"] == agents[i]].Proportion, name = "Head", marker = dict(color = colors[i]),
                    showlegend=False)
    bod = go.Box(y=body[body["Agent"] == agents[i]].Proportion, name = "Body", marker = dict(color = colors[i]),
                    showlegend=False)
    ey = go.Box(y=eye[eye["Agent"] == agents[i]].Proportion, name = "Eye", marker = dict(color = colors[i]),
                    showlegend=False)
    pv = go.Box(y=posverb[posverb["Agent"] == agents[i]].Proportion, name = "Positive Verbal", marker = dict(color = colors[i]),
                    showlegend=False)
    ackno = go.Box(y=ack[ack["Agent"] == agents[i]].Proportion, name = "Acknowledgement Verbal", marker = dict(color = colors[i]),
                    showlegend=False)
    negative = go.Box(y=negV[negV["Agent"] == agents[i]].Proportion, name = "Negative Verbal", marker = dict(color = colors[i]),
                    showlegend=False)
    traces.append(current)
    traces.append(nonverb)
    traces.append(bod)
    traces.append(ey)
    traces.append(pv)
    traces.append(ackno)
    traces.append(negative)
    
    
    
fig.add_traces(traces)

fig.update_layout(
        legend_title_text='Agent',
        yaxis_title='Proportion of Behaviors',
        xaxis_title='Agent',
        title ='Mismatch Behaviors Split by Categories' ,
        width=800, height=800,
        plot_bgcolor = 'white',
        boxmode = 'group',
        boxgap = 0.0001,
        boxgroupgap = 0.001)


dfs = [body, eye, posverb,ack,negV, hand, head]
labels = ["body", "eye", "posverb", "ack", "negV", "hand", "head"]

#Isolate the positive values for each agent
for i in range(len(dfs)):
    print(labels[i].capitalize())
    anova_oneway(dfs[i])

fig.update_yaxes(gridcolor='#D3D3D3')               
fig.show()
Body
One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.8182507955563594
Jibo vs. Computer P-Value: 0.6823391878880662
Alexa vs. Computer P-Value: 0.7217223119575016
Eye
One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.0724497708715665
Jibo vs. Computer P-Value: 0.060399562601138615
Alexa vs. Computer P-Value: 0.902792692393342
Posverb
One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.7130314577752701
Jibo vs. Computer P-Value: 0.2911313012025224
Alexa vs. Computer P-Value: 0.2175521550961706
Ack
One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.8966512416965987
Jibo vs. Computer P-Value: 0.531344780839478
Alexa vs. Computer P-Value: 0.6211617570461558
Negv
One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.45714970175045044
Jibo vs. Computer P-Value: 0.6784437112036521
Alexa vs. Computer P-Value: 0.22100970229607225
Hand
One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.5498042580432531
Jibo vs. Computer P-Value: 0.8124895591345886
Alexa vs. Computer P-Value: 0.42203709550755186
Head
One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.39472895324867974
Jibo vs. Computer P-Value: 0.04113838463931391
Alexa vs. Computer P-Value: 0.2722974233033866

In Sync vs. Mismatch Across All:

In [44]:
sync = behavior[["Family","Participant","Agent","Description", "InSync", "Type"]]

#Group by participant and calculate proportions 
sync = sync.groupby([ "Participant", 'Agent', 'InSync']).size().reset_index(name='counts')
totals = sync.groupby("Participant")[['counts']].sum().reset_index()
sync = pd.merge(sync, totals, on="Participant")
sync['Proportion'] = sync["counts_x"]/sync["counts_y"]

#Want to isolate the positive values
mismatch = sync[sync['InSync'] == 0]
sync = sync[sync['InSync'] == 1]

syncFigure = go.FigureWidget()
#Create a box for each agent and append to overall plot - adapted & modified from previous notebooks 
syncTraces = []
for i in range(len(agents)):
    current = go.Box(y=sync[sync["Agent"] == agents[i]].Proportion, name = "<b>In-Sync</b>", marker = dict(color = colors[i]),
                    showlegend = False)
    mismatched = go.Box(y=mismatch[mismatch["Agent"] == agents[i]].Proportion, name = "<b>Mismatch</b>", marker = dict(color = colors[i]),
                    showlegend=False)
    syncTraces.append(current)
    syncTraces.append(mismatched)
    
syncFigure.add_traces(syncTraces)


syncFigure.update_layout(
        legend_title_text='Agent',
    
        title_text ='<b>Synchrony of Agent and User Sentiment</b>' ,
        width=800, height=800,
        plot_bgcolor = 'white',
        boxmode = 'group',
        font=dict(
        size=20,
        color="#000000",
        family="Calibri, Body",)
    

       
)

syncFigure.update_yaxes(gridcolor='#D3D3D3')  
syncFigure.update(layout=dict(title=dict(x=0.5)))
syncFigure.show()
syncFigure.write_image("images/sync.svg")
In [45]:
#across the three agents - sync
stats.f_oneway(sync[(sync["Agent"] == "Jibo")].Proportion,sync[(sync["Agent"] == "Computer")].Proportion,sync[(sync["Agent"] == "Alexa")].Proportion)
Out[45]:
F_onewayResult(statistic=43.20667947573124, pvalue=5.372915046483051e-14)
In [46]:
#across the three agents - mismatch
stats.f_oneway(mismatch[(mismatch["Agent"] == "Jibo")].Proportion,mismatch[(mismatch["Agent"] == "Computer")].Proportion,mismatch[(mismatch["Agent"] == "Alexa")].Proportion)
Out[46]:
F_onewayResult(statistic=3.070561993568935, pvalue=0.051971425322732356)
In [47]:
#model for sync
model = ols('Proportion ~ C(Agent)', data=sync).fit()
anova_table = sm.stats.anova_lm(model, typ=2)
anova_table
Out[47]:
sum_sq df F PR(>F)
C(Agent) 1.191994 2.0 43.206679 5.372915e-14
Residual 1.282851 93.0 NaN NaN
In [48]:
#model for mismatch
model = ols('Proportion ~ C(Agent)', data=mismatch).fit()
anova_table = sm.stats.anova_lm(model, typ=2)
anova_table
Out[48]:
sum_sq df F PR(>F)
C(Agent) 0.021658 2.0 3.070562 0.051971
Residual 0.278607 79.0 NaN NaN
In [49]:
anova_oneway(sync)
One Way ANOVAs:
Jibo vs. Alexa P-Value: 6.502083808567628e-11
Jibo vs. Computer P-Value: 1.8887556799637473e-09
Alexa vs. Computer P-Value: 0.7920848795764446
In [50]:
anova_oneway(mismatch)
One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.05497236139751887
Jibo vs. Computer P-Value: 0.04492353198943353
Alexa vs. Computer P-Value: 0.9445841640395525
In [51]:
MultiComp = MultiComparison(sync['Proportion'],sync["Agent"])
print(MultiComp.tukeyhsd().summary())
 Multiple Comparison of Means - Tukey HSD, FWER=0.05  
======================================================
 group1   group2  meandiff p-adj  lower  upper  reject
------------------------------------------------------
   Alexa Computer   0.0063   0.9 -0.0642 0.0768  False
   Alexa     Jibo   0.2378 0.001  0.1678 0.3077   True
Computer     Jibo   0.2314 0.001   0.162 0.3008   True
------------------------------------------------------
In [52]:
MultiComp = MultiComparison(mismatch['Proportion'],mismatch["Agent"])
print(MultiComp.tukeyhsd().summary())
  Multiple Comparison of Means - Tukey HSD, FWER=0.05  
=======================================================
 group1   group2  meandiff p-adj   lower  upper  reject
-------------------------------------------------------
   Alexa Computer   0.0009    0.9  -0.037 0.0389  False
   Alexa     Jibo   0.0354  0.083 -0.0036 0.0744  False
Computer     Jibo   0.0345 0.0867 -0.0038 0.0728  False
-------------------------------------------------------
In [53]:
print('Computer: ', statistics.mean(sync[(sync["Agent"] == "Computer")].Proportion))
print('Jibo: ', statistics.mean(sync[(sync["Agent"] == "Jibo")].Proportion))
print('Alexa: ', statistics.mean(sync[(sync["Agent"] == "Alexa")].Proportion))
Computer:  0.14060214857628014
Jibo:  0.372037202293913
Alexa:  0.1342770222253532
In [54]:
print('Computer: ', statistics.stdev(sync[(sync["Agent"] == "Computer")].Proportion))
print('Jibo: ', statistics.stdev(sync[(sync["Agent"] == "Jibo")].Proportion))
print('Alexa: ', statistics.stdev(sync[(sync["Agent"] == "Alexa")].Proportion))
Computer:  0.11066507271621567
Jibo:  0.15152017612693877
Alexa:  0.07495194637076107

Individual Behaviors:

In [55]:
#Group all behaviors as either positive, notpositive, mismatch, or insync 

temp = behavior
total = temp[["Participant","Agent","Description", "Positive", "InSync" ]]

total = total.groupby(['Participant','Agent', 'Description', "Positive", "InSync"]).size().reset_index(name='counts')
combined = total.groupby('Participant')[['counts']].sum().reset_index()
allBehaviors = pd.merge(total, combined, on='Participant')
allBehaviors['Proportion'] = allBehaviors["counts_x"]/allBehaviors["counts_y"]

allBehaviorsP = allBehaviors[allBehaviors['Positive'] == 1]
allBehaviorsN = allBehaviors[allBehaviors['Positive'] == 0]

allBehaviorsM = allBehaviors[allBehaviors['InSync'] == 0]
allBehaviorsS= allBehaviors[allBehaviors['InSync'] == 1]
In [56]:
#Isolate the data for each behavior and make its own sub-df to prepare for plotting 

#Categories 
singleBehaviorDFsP = []
singleBehaviorDFsN = []
singleBehaviorDFs = []

singleBehaviorDFsM = []
singleBehaviorDFsS = []

for behavior in behaviors:
    tempP = allBehaviorsP
    tempN = allBehaviorsN
    tempM = allBehaviorsM
    tempS = allBehaviorsS
    
    tempAll = allBehaviors
    
    tempP = tempP[tempP['Description']==behavior]
    singleBehaviorDFsP.append(tempP)
    
    tempN = tempN[tempN['Description']==behavior]
    singleBehaviorDFsN.append(tempN)
    
    tempS = tempS[tempS['Description']==behavior]
    singleBehaviorDFsS.append(tempS)
    
    tempM = tempM[tempM['Description']==behavior]
    singleBehaviorDFsM.append(tempM)
    
    tempAll = tempAll[tempAll['Description']==behavior]
    singleBehaviorDFs.append(tempAll)
In [57]:
#Will plot one behavior individually 
def makeBoxplot(df, behavior):    
    fig = go.Figure()
    traces = []

    for i in range(len(agents)):  
        currentTrace = go.Box(y=df[df['Agent'] == agents[i]].Proportion, x = df['Description'], name = agents[i].capitalize(), marker = dict(color = colors[i]))
        traces.append(currentTrace)
        

        fig.update_layout(
        legend_title_text='Agent',
        yaxis_title='Proportion of Behaviors',
        xaxis_title='Behavior: ' + behavior,
        xaxis = dict(showticklabels=False),
        title ='Behavior Grouped by Participant: ' + behavior,
        width=900, height=600,
        plot_bgcolor = 'white',
        
        boxmode = 'group')
    fig.add_traces(traces)
    fig.update_yaxes(gridcolor='#D3D3D3')
    return fig

Example Behavior: Glance

In [58]:
#plot glance at others
fig = go.Figure()
traces = []

jibo = go.Box(y= allBehaviors[(allBehaviors["Agent"] == 'Jibo') & (allBehaviors["Description"] == 'Glance at Others')].Proportion, name = 'jibo', 
                  marker = dict(color = 'rgb(238,166,101)'))
alexa = go.Box(y= allBehaviors[(allBehaviors["Agent"] == 'Alexa') & (allBehaviors["Description"] == 'Glance at Others')].Proportion, name = 'alexa', 
                  marker = dict(color = 'rgb(238,199,188)'))
computer = go.Box(y= allBehaviors[(allBehaviors["Agent"] == 'Computer') & (allBehaviors["Description"] == 'Glance at Others')].Proportion, name = 'computer', 
                  marker = dict(color = 'rgb(154,196,196)'))

traces.append(jibo)
traces.append(alexa)
traces.append(computer)

fig.add_traces(traces)

group_labels = ['J', 'A', 'C']
colors = ['rgb(238,166,101)', 'rgb(238,199,188)', 'rgb(154,196,196)', 'rgb(215,189,209)']

fig.show()
In [59]:
#across the three agents - glance at others
stats.f_oneway(allBehaviors[(allBehaviors["Agent"] == 'Jibo') & (allBehaviors["Description"] == 'Glance at Others')].Proportion,
              allBehaviors[(allBehaviors["Agent"] == 'Alexa') & (allBehaviors["Description"] == 'Glance at Others')].Proportion,
              allBehaviors[(allBehaviors["Agent"] == 'Computer') & (allBehaviors["Description"] == 'Glance at Others')].Proportion)
Out[59]:
F_onewayResult(statistic=20.150272985456592, pvalue=1.8458840613883216e-08)
In [60]:
frames = [allBehaviors[(allBehaviors["Agent"] == 'Jibo') & (allBehaviors["Description"] == 'Glance at Others')],
              allBehaviors[(allBehaviors["Agent"] == 'Alexa') & (allBehaviors["Description"] == 'Glance at Others')],
              allBehaviors[(allBehaviors["Agent"] == 'Computer') & (allBehaviors["Description"] == 'Glance at Others')]]

glance = pd.concat(frames)
In [61]:
#model for glance at others
model = ols('Proportion ~ C(Agent)', data=glance).fit()
anova_table = sm.stats.anova_lm(model, typ=2)
anova_table
Out[61]:
sum_sq df F PR(>F)
C(Agent) 0.036228 2.0 20.150273 1.845884e-08
Residual 0.132145 147.0 NaN NaN
In [62]:
MultiComp = MultiComparison(glance['Proportion'],glance["Agent"])
print(MultiComp.tukeyhsd().summary())
 Multiple Comparison of Means - Tukey HSD, FWER=0.05  
======================================================
 group1   group2  meandiff p-adj  lower  upper  reject
------------------------------------------------------
   Alexa Computer   0.0001   0.9 -0.0147 0.0149  False
   Alexa     Jibo   0.0321 0.001  0.0184 0.0458   True
Computer     Jibo   0.0319 0.001  0.0175 0.0464   True
------------------------------------------------------
In [63]:
print('Computer: ', statistics.mean(glance[(glance["Agent"] == "Computer")].Proportion))
print('Jibo: ', statistics.mean(glance[(glance["Agent"] == "Jibo")].Proportion))
print('Alexa: ', statistics.mean(glance[(glance["Agent"] == "Alexa")].Proportion))
Computer:  0.025795189608278635
Jibo:  0.0577413180288611
Alexa:  0.025665155885968842
In [64]:
print('Computer: ', statistics.stdev(glance[(glance["Agent"] == "Computer")].Proportion))
print('Jibo: ', statistics.stdev(glance[(glance["Agent"] == "Jibo")].Proportion))
print('Alexa: ', statistics.stdev(glance[(glance["Agent"] == "Alexa")].Proportion))
Computer:  0.014760148594949974
Jibo:  0.0447959263895031
Alexa:  0.0147233573639982

Combined Inter-Group Behaviors

In [65]:
frames = [allBehaviors[(allBehaviors["Agent"] == 'Jibo') & (allBehaviors["Description"] == 'Glance at Others')],
              allBehaviors[(allBehaviors["Agent"] == 'Alexa') & (allBehaviors["Description"] == 'Glance at Others')],
              allBehaviors[(allBehaviors["Agent"] == 'Computer') & (allBehaviors["Description"] == 'Glance at Others')],
              allBehaviors[(allBehaviors["Agent"] == 'Jibo') & (allBehaviors["Description"] == 'Whisper')],
              allBehaviors[(allBehaviors["Agent"] == 'Alexa') & (allBehaviors["Description"] == 'Whisper')],
              allBehaviors[(allBehaviors["Agent"] == 'Computer') & (allBehaviors["Description"] == 'Whisper')],
              allBehaviors[(allBehaviors["Agent"] == 'Jibo') & (allBehaviors["Description"] == 'Defend')],
              allBehaviors[(allBehaviors["Agent"] == 'Alexa') & (allBehaviors["Description"] == 'Defend')],
              allBehaviors[(allBehaviors["Agent"] == 'Computer') & (allBehaviors["Description"] == 'Defend')],
         ]
In [66]:
inter_group = pd.concat(frames)
inter_group
Out[66]:
Participant Agent Description Positive InSync counts_x counts_y Proportion
5 P1 Jibo Glance at Others 1 1 3 14 0.214286
28 P10 Jibo Glance at Others 0 0 2 55 0.036364
29 P10 Jibo Glance at Others 0 1 1 55 0.018182
30 P10 Jibo Glance at Others 1 1 5 55 0.090909
68 P11 Jibo Glance at Others 0 0 5 66 0.075758
... ... ... ... ... ... ... ... ...
883 P38 Computer Whisper 999 999 1 108 0.009259
66 P11 Jibo Defend 0 1 1 66 0.015152
96 P12 Jibo Defend 0 1 1 43 0.023256
142 P14 Jibo Defend 0 1 1 39 0.025641
837 P37 Jibo Defend 1 1 3 84 0.035714

201 rows × 8 columns

In [67]:
#plot inter-group
human = go.Figure()
humanTraces = []

jibo = go.Box(y= inter_group[(inter_group["Agent"] == 'Jibo')].Proportion, name = '<b>Jibo</b>', 
                  marker = dict(color = 'rgb(238,166,101)'))
alexa = go.Box(y= inter_group[(inter_group["Agent"] == 'Alexa')].Proportion, name = '<b>Alexa</b>', 
                  marker = dict(color = 'rgb(238,199,188)'))
computer = go.Box(y= inter_group[(inter_group["Agent"] == 'Computer')].Proportion, name = '<b>Computer</b>', 
                  marker = dict(color = 'rgb(154,196,196)'))

humanTraces.append(jibo)
humanTraces.append(alexa)
humanTraces.append(computer)

human.add_traces(humanTraces)

group_labels = ['J', 'A', 'C']
colors = ['rgb(238,166,101)', 'rgb(238,199,188)', 'rgb(154,196,196)', 'rgb(215,189,209)']


human.update_layout(
        legend_title_text='<b>Agent</b>',
        title_text ='<b>Human-Human Interactions</b>' ,
        width=800, height=800,
        plot_bgcolor = 'white',
        boxmode = 'group',
        font=dict(
        size=20,
        color="#000000",
        family="Calibri, Body",)
)

human.update_yaxes(gridcolor='#D3D3D3')  
human.update(layout=dict(title=dict(x=0.5)))
human.show()
In [68]:
human.write_image("images/human.svg")
In [69]:
#across the three agents - inter_group
stats.f_oneway(inter_group[(inter_group["Agent"] == 'Jibo')].Proportion,
              inter_group[(inter_group["Agent"] == 'Alexa')].Proportion,
              inter_group[(inter_group["Agent"] == 'Computer')].Proportion)
Out[69]:
F_onewayResult(statistic=19.987923796248797, pvalue=1.2390775465620557e-08)
In [70]:
anova_oneway(inter_group)
One Way ANOVAs:
Jibo vs. Alexa P-Value: 4.017584959203143e-06
Jibo vs. Computer P-Value: 6.982885905690416e-06
Alexa vs. Computer P-Value: 0.7308713204960655
In [71]:
#model for inter group
model = ols('Proportion ~ C(Agent)', data=inter_group).fit()
anova_table = sm.stats.anova_lm(model, typ=2)
anova_table
Out[71]:
sum_sq df F PR(>F)
C(Agent) 0.035424 2.0 19.987924 1.239078e-08
Residual 0.175456 198.0 NaN NaN
In [72]:
MultiComp = MultiComparison(inter_group['Proportion'],inter_group["Agent"])
print(MultiComp.tukeyhsd().summary())
 Multiple Comparison of Means - Tukey HSD, FWER=0.05  
======================================================
 group1   group2  meandiff p-adj  lower  upper  reject
------------------------------------------------------
   Alexa Computer  -0.0012   0.9 -0.0141 0.0118  False
   Alexa     Jibo   0.0265 0.001  0.0149 0.0381   True
Computer     Jibo   0.0276 0.001  0.0152   0.04   True
------------------------------------------------------
In [73]:
print('Computer: ', statistics.mean(inter_group[(inter_group["Agent"] == "Computer")].Proportion))
print('Jibo: ', statistics.mean(inter_group[(inter_group["Agent"] == "Jibo")].Proportion))
print('Alexa: ', statistics.mean(inter_group[(inter_group["Agent"] == "Alexa")].Proportion))
Computer:  0.026520405643490414
Jibo:  0.05415811153527391
Alexa:  0.0276742168212052
In [74]:
print('Computer: ', statistics.stdev(inter_group[(inter_group["Agent"] == "Computer")].Proportion))
print('Jibo: ', statistics.stdev(inter_group[(inter_group["Agent"] == "Jibo")].Proportion))
print('Alexa: ', statistics.stdev(inter_group[(inter_group["Agent"] == "Alexa")].Proportion))
Computer:  0.015440336740174337
Jibo:  0.04111741633839996
Alexa:  0.020044960457591257

Plotting & Running ANOVA:

In [82]:
def plotBoxes(listofDFs):
    nonempty = []
    for df in listofDFs:
 
        if list(df['Description']) != []: 
            label = list(df['Description'])[0]
            nonempty.append(label)
            current = makeBoxplot(df, label)
            
            #Uncomment below to plot and store the output as .png 
            current.show()
            # current.write_image("all/" + str(label) + ".png")

            print("\n",label, "\n")
            anova_oneway(df)
In [83]:
plotBoxes(singleBehaviorDFs)
 Short Response 

One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.75804539961906
Jibo vs. Computer P-Value: 0.9773188643291311
Alexa vs. Computer P-Value: 0.805018214518806
 Mhm 

One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.5361167586215495
Jibo vs. Computer P-Value: 0.1452915182667211
Alexa vs. Computer P-Value: 0.5417672613366643
 Answer Question 

One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.6212920726606832
Jibo vs. Computer P-Value: 0.29834126619961154
Alexa vs. Computer P-Value: 0.23195119331780278
 Follow-Up Question 

One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.9929087490084139
Jibo vs. Computer P-Value: 0.3105622652074166
Alexa vs. Computer P-Value: 0.4316441013768846
 Exclamation 

One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.5253853359471294
Jibo vs. Computer P-Value: 0.151973576346179
Alexa vs. Computer P-Value: 0.7151978551180327
 Relevancy 

One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.03806590765932419
Jibo vs. Computer P-Value: 0.030091188903455066
Alexa vs. Computer P-Value: 0.5885074747710131
 Move Toward 

One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.06348531852803266
Jibo vs. Computer P-Value: 0.005661186028390817
Alexa vs. Computer P-Value: 0.13455547453068087
 Move Away 

One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.44344209110514987
Jibo vs. Computer P-Value: 0.5714168265097037
Alexa vs. Computer P-Value: 0.6229069603824162
 Point 

One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.2109302054688693
Jibo vs. Computer P-Value: 0.57177980921275
Alexa vs. Computer P-Value: 0.12178046742237417
 Shrug 

One Way ANOVAs:
Jibo vs. Alexa P-Value: nan
Jibo vs. Computer P-Value: 0.9490408397026986
Alexa vs. Computer P-Value: nan
 Luring 

One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.34260004844545594
Jibo vs. Computer P-Value: nan
Alexa vs. Computer P-Value: nan
 Tilt Head 

One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.44632470104181476
Jibo vs. Computer P-Value: 0.17452302973422001
Alexa vs. Computer P-Value: 0.7905122979007007
 Imitation 

One Way ANOVAs:
Jibo vs. Alexa P-Value: nan
Jibo vs. Computer P-Value: nan
Alexa vs. Computer P-Value: nan
 Imitation Dance 

One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.5911681939639782
Jibo vs. Computer P-Value: nan
Alexa vs. Computer P-Value: nan
 Generic Dance 

One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.991166954291467
Jibo vs. Computer P-Value: 0.8561467689133242
Alexa vs. Computer P-Value: 0.8329766749333635
 Waving 

One Way ANOVAs:
Jibo vs. Alexa P-Value: nan
Jibo vs. Computer P-Value: nan
Alexa vs. Computer P-Value: nan
 Hand Gesture 

One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.5123529117994342
Jibo vs. Computer P-Value: 0.35274248990569607
Alexa vs. Computer P-Value: 0.39351974098668147
 Switch Eye Contact 

One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.13844759691420597
Jibo vs. Computer P-Value: 0.1247214116285498
Alexa vs. Computer P-Value: 0.8971603842615599
 Look Away 

One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.06801126144380837
Jibo vs. Computer P-Value: 0.05403556567766348
Alexa vs. Computer P-Value: 0.5302905246280203
 Glance at Others 

One Way ANOVAs:
Jibo vs. Alexa P-Value: 3.7431780693484676e-06
Jibo vs. Computer P-Value: 2.3625058512523126e-05
Alexa vs. Computer P-Value: 0.9663221618422602
 Smile 

One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.00017295357143510783
Jibo vs. Computer P-Value: 0.0025465382344249696
Alexa vs. Computer P-Value: 0.5959283896686743
 Judgemental Eyebrow 

One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.02585087557022203
Jibo vs. Computer P-Value: 0.9453320565213735
Alexa vs. Computer P-Value: 0.0072549747397535275
 Inquisitive Eyebrow 

One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.25546804791463
Jibo vs. Computer P-Value: 0.19453502122882482
Alexa vs. Computer P-Value: 0.6958196959872651
 Downward Frown 

One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.4502885976240496
Jibo vs. Computer P-Value: 0.3832065099748908
Alexa vs. Computer P-Value: 0.854829157439625
 Mouth Open 

One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.6503136283713429
Jibo vs. Computer P-Value: 0.438878987908934
Alexa vs. Computer P-Value: 0.20974304427450763
 Whisper 

One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.15771820526745706
Jibo vs. Computer P-Value: 0.054548460297123694
Alexa vs. Computer P-Value: 0.6331949198645743
 Laugh 

One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.0027598152015470066
Jibo vs. Computer P-Value: 0.24599273460041746
Alexa vs. Computer P-Value: 0.4979722485951714
 Thank You 

One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.5857764513011396
Jibo vs. Computer P-Value: 0.4290583305353667
Alexa vs. Computer P-Value: 0.08040679053499493
 Compliment 

One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.35176917805891594
Jibo vs. Computer P-Value: 0.09948713887367394
Alexa vs. Computer P-Value: nan
 Defend 

One Way ANOVAs:
Jibo vs. Alexa P-Value: nan
Jibo vs. Computer P-Value: nan
Alexa vs. Computer P-Value: nan
 Insult 

One Way ANOVAs:
Jibo vs. Alexa P-Value: nan
Jibo vs. Computer P-Value: nan
Alexa vs. Computer P-Value: 0.042102712226472966
 Judgemental Verbal 

One Way ANOVAs:
Jibo vs. Alexa P-Value: 0.30730273387346047
Jibo vs. Computer P-Value: 0.19676833056659337
Alexa vs. Computer P-Value: 0.6766988584286843
 Angry Verbal 

One Way ANOVAs:
Jibo vs. Alexa P-Value: nan
Jibo vs. Computer P-Value: nan
Alexa vs. Computer P-Value: 0.12032975429889163
In [78]:
# plotBoxes(singleBehaviorDFsP)
# plotBoxes(singleBehaviorDFsN)
# plotBoxes(singleBehaviorDFsM)
# plotBoxes(singleBehaviorDFsS)
In [ ]: